package main

import "fmt"

func main() {
	//var intArr [5]int = [...]int{1, 2, 4, 5, 6}
	//// 声明/定义一个切片
	//// var slice = intArr[1:5]
	//// 其中slice是切片名称
	//// intArr[1:5]表示slice引用到intArr这个数组
	//// 引用intArr数组的起始下标为1，终止下标为5，但是不包含5
	//var slice = intArr[2:3]
	//printArrAndSlice(&intArr, slice)
	//fmt.Println("----------change intArr ------------")
	//intArr[2] = 123123
	//printArrAndSlice(&intArr, slice)
	//fmt.Println("----------------------------------------------------")
	//usageOfSlice()
	//fmt.Println("----------------------------------------------------")
	//sliceTraversal()
	//fmt.Println("----------------------------------------------------")
	//sliceAppend()
	//fmt.Println("----------------------------------------------------")
	//sliceCopy()
	//fmt.Println("----------------------------------------------------")
	//stringSlice()
	execFbn(10)
}

func printArrAndSlice(intArr *[5]int, slice []int) {
	fmt.Println("intArr: ", *intArr)
	fmt.Println("slice", slice)
	fmt.Println("slice 的长度", len(slice))
	// 这里的容量是原数组长度减去左下标对应的长度
	fmt.Println("slice 的容量", cap(slice))
	fmt.Println("intArr元素2的地址", &(*intArr)[2])
	fmt.Println("slice元素1的地址", &slice[0])
}

func usageOfSlice() {
	// 方式1: 定义一个切片，然后让切片引用一个已经创建好的数组
	var arr1 [5]int = [...]int{2, 3, 4, 56, 3}
	var slice1 = arr1[0:2]
	fmt.Println("Usage 1: slice1", slice1)

	// 方式2: 通过make来创建切片
	var slice2 []int = make([]int, 10, 20)
	slice2[3] = 10
	slice2[9] = 20
	fmt.Println("Usage 2: slice2", slice2)

	// 方式3: 定义一个切片，直接就指定具体数组，使用原理类似make的方式
	var slice3 []string = []string{"slice1", "slice2", "slice3"}
	fmt.Println("Usage 3: slice3", slice3)

	// 切片可以继续切
	var slice4 = slice2[:20]
	fmt.Println("slice4", slice4)
}

func sliceTraversal() {
	var arr [7]int = [...]int{5, 1, 23, 9, 7, 8, 3}
	var slice = arr[:6]
	for i := 0; i < len(slice); i++ {
		fmt.Printf("slice[%d] = %d\n", i, slice[i])
	}
	fmt.Println("----------------------")

	for index, value := range slice {
		fmt.Printf("slice[%d] = %d\n", index, value)
	}
}

func sliceAppend() {
	var slice []int = []int{100, 23, 24, 67, 43, 789}
	fmt.Println(slice)
	fmt.Printf("slice=%v, address=%v\n", slice, &slice[0])
	fmt.Println("----------------------")
	slice = append(slice, 1456, 534, 534, 534, 534, 53, 4534, 5)
	fmt.Printf("slice=%v, address=%v\n", slice, &slice[0])
	fmt.Println("----------------------")
	slice = append(slice, slice...)
	fmt.Printf("slice=%v, address=%v\n", slice, &slice[0])

}

func sliceCopy() {
	var slice1 []int = []int{1, 2, 3, 4, 5}
	var slice2 []int = make([]int, 1)
	copy(slice2, slice1)
	fmt.Println(slice2)
}

func stringSlice() {
	var str string = "asdajsda"
	var slice = str[:4]
	fmt.Printf("slice type=%T\n", slice)
	// str[0] = 'z'   这是错的！！！！
	// 想修改字符串用以下方法
	var byteStr []byte = []byte(str)
	byteStr[1] = 'h'
	str = string(byteStr)
	fmt.Println(str)

	var str2 = "阿斯顿"
	var runeStr []rune = []rune(str2)
	runeStr[0] = '不'
	str2 = string(runeStr)
	fmt.Println(str2)
}

func execFbn(n int) {
	// 可以接收一个n int
	// 可以将斐波那契的数列放到切片中
	// 斐波那契数列形式：
	//arr[0] = 1;arr[1] = 1;arr[2] = 2;arr[3] = 3;arr[4] = 5;arr[5] = 8
	fmt.Println("期望的斐波那契长度为：", n)
	fbnSlice := make([]uint64, n)
	var i int = 0
	for ; i < n; i++ {
		if i >= 2 {
			break
		} else {
			fbnSlice[i] = 1
		}
	}
	for ; i < n; i++ {
		fbnSlice[i] = fbnSlice[i-1] + fbnSlice[i-2]
	}
	fmt.Println("斐波那契数列为：", fbnSlice)
}
